package com.dream.libxrec.rec;

import android.content.Context;
import android.media.MediaCodec;
import android.media.MediaFormat;
import android.util.Log;
import com.dream.libxrec.encode.audio.IAudioEncoder;
import com.dream.libxrec.encode.audio.IAudioEncoderListener;
import com.dream.libxrec.encode.video.IVideoEncoder;
import com.dream.libxrec.encode.video.IVideoEncoderListener;
import java.nio.ByteBuffer;

public class Mp4RecordHelper {

    private final Context mContext;

    private String mVideoPath = null;//录像地址

    private final Mp4MediaMuxer mp4MediaMuxer =
            new Mp4MediaMuxer();//MP4封装器

    private final IVideoEncoder mVideoEncoder;//视频采集及编码器

    private final IAudioEncoder mAudioEncoder;//音频采集及编码器

    private MediaFormat mAudioFormat,mVideoFormat;//音视频编码信息

    private final IAudioEncoderListener mAudioEncoderListener =
            new IAudioEncoderListener() {
        @Override
        public void onFormat(MediaFormat format) {
            mAudioFormat = format;
            Log.i("MediaFormat","audio format");
            startMuxer();
        }

        @Override
        public void onFrame(ByteBuffer buffer, MediaCodec.BufferInfo info) {
            mp4MediaMuxer.writeAudioFrame(buffer,info);
        }

        @Override
        public void onFrame(byte[] buffer, int size,
                            long pts) {

        }
    };

    private final IVideoEncoderListener mVideoEncoderListener =
            new IVideoEncoderListener() {
        @Override
        public void onFormat(MediaFormat format) {
            Log.i("MediaFormat","audio format");
            mVideoFormat = format;
            startMuxer();
        }

        @Override
        public void onFrame(ByteBuffer buffer, MediaCodec.BufferInfo info) {
            mp4MediaMuxer.writeVideoFrame(buffer,info);
        }

        @Override
        public void onFrame(boolean isIFrame, byte[] buffer
                , int size, long pts) {

        }
    };

    /**
     * 视频录制处理器，音频和视频两者可有一项为空，不影响录制
     * @param ct
     * @param videoEncoder 视频采集及编码器
     * @param audioEncoder 音频采集及编码器
     */
    public Mp4RecordHelper(Context ct, IVideoEncoder videoEncoder,
                           IAudioEncoder audioEncoder){
        this.mContext = ct;
        this.mAudioEncoder = audioEncoder;
        this.mVideoEncoder = videoEncoder;
        if (mVideoEncoder != null){
            this.mVideoEncoder.addIEncoderListener(mVideoEncoderListener);
        }

        if (mAudioEncoder != null){
            this.mAudioEncoder.addIEncoderListener(mAudioEncoderListener);
        }
    }

    public void start(String path){
        this.mVideoPath = path;
        if (mAudioEncoder != null){
            mAudioEncoder.start();
        }

        if (mVideoEncoder != null){
            mVideoEncoder.start();
        }
    }

    private void startMuxer() {

        if (mVideoEncoder != null&&mVideoFormat == null){
            return;
        }

        if (mAudioEncoder != null&&mAudioFormat == null){
            return;
        }

        Log.i("Muxer","start recording");
        mp4MediaMuxer.start(mAudioFormat
                , mVideoFormat, new Mp4MediaMuxer.IMuxerBuilder() {
                    @Override
                    public String getFilePath() {
                        return null;
                    }

                    @Override
                    public boolean isEndFile(long recTime) {
                        return false;
                    }
                });
    }

    /**
     * 关闭视频及音频的采集，结束编码器及MP4封装
     */
    public String closeAll(){

        if (mAudioEncoder != null){
            try {
                mAudioEncoder.stop();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        if (mVideoEncoder != null){
            try {
                mVideoEncoder.stop();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        Log.i("Muxer","stop recording");
        //一定要调用MediaMuxer.release();否则mp4文件无法正常播放
        mp4MediaMuxer.stop();

        return mVideoPath;
    }


}